#ifndef __CZF_TEXT_LINE_H__
#define __CZF_TEXT_LINE_H__


#include "vararryt.h"

typedef CVarArrayT<char> CVarChars;

#define LINE_INIT_LEN 10
#define LEN_GROW_STEP 10

#define IS_ASCII(c) ((unsigned char)c <= 0x7F)
#define IS_LEADING_CHAR(c) (((unsigned char)c >= 0x81 ) && ((unsigned char)c <= 0xfe))
#define IS_TRAILING_CHAR(c) (((unsigned char)c >= 0x40) && ((unsigned char)c <=0x7e) || \
                             ((unsigned char)c >=0x80) && ((unsigned char)c <=0xfe) )
#define IS_2ND_4TH_CHAR(c) ((unsigned char)c >= 0x30 && (unsigned char) c <= 0x39) 


class CTextLine : public CVarChars
{
public:
    CTextLine ();
    virtual ~CTextLine();

    // InsertTextAt insert text at index idx, and retures the strlen
    //  of the new string.
    unsigned int InsertTextAt (unsigned int idx, const char* text);

    // RemoveText removes text from index start to end.
    // returns strlen of the new string.
    unsigned int RemoveText (unsigned int start, unsigned int end); 
    // A Wrapper of GetMultiByteChar
    unsigned int GetNextCharacter ( unsigned int start, unsigned long* charater, int* len);
    unsigned int DisplayColToIndex (unsigned int col, unsigned int tabsize, bool rightalign=false);
    unsigned int IndexToDisplayCol (unsigned int idx, unsigned int tabsize);
    unsigned int GetTotalCols(unsigned int tabsize);
    // GetIdxForRemoveLeadingSpacesBefore calculates to which char should be removed for RemoveLeadingSpacesBefore
    unsigned int GetIdxForRemoveLeadingSpacesBefore (unsigned int idx);
    void RemoveLeadingSpacesBefore(unsigned int idx);

    /* FindInLineForward searchs str in this line starting from start and ending at end.
     * If found, returns true and found_idx is updated to the start index of the found.
     */
    bool FindInLineForward (unsigned int start, unsigned int end, const char* str, unsigned int* found_idx);
    /* FindInLineBackWard searchs str in this line starting from start and ending at end.
     *  start <= end.
     * If found, returns true and found_idx is updated to the start index of the found.
     */
    bool FindInLineBackward (unsigned int start, unsigned int end, const char* str, unsigned int* found_idx);
    /* GetLeadingSpaces returns a string which copies the leading spaces of this line.
     *  Caller need to free it by calling free().
     */
    char* GetLeadingSpaces();
    /* GetLastToken returns a string which copies the last token of this line.
     *  Caller need to free it by calling free().
     */
    char* GetLastToken();
    /* GetFirstTokenAndPos returns a string which copies the first token of this line. The start index is stored in *start
     *  Caller need to free it by calling free().
     */
    char* GetFirstTokenAndPos(unsigned int* start);
    /* GetTokenByIndex returns the length of the found token. start of the token is stored in *start.
     *  This is called when user double click the word, then this function is called to
     *  determine the actually place of the word. 
     */
    unsigned int GetTokenByIndex(unsigned int idx, unsigned int* start);
};

#define EOL     (unsigned int)(-1)
// Get the starting position of next multi byte char in "text", 
//  found character is stored in *character, *len stores the len of the character.
//  returns the starting position of next character.
//  returns EOL if reaches the end of the line ('\0').
unsigned int GetMultiByteChar(const char* text, unsigned int start, 
                     unsigned long* character, int* len);
// Check whether the byte is inside a multi-byte char defined by GB18030
bool InsideMultiByteChar(const char* text, unsigned int idx);

#endif /* __CZF_TEXT_LINE_H__*/
